/* ================================================================================
//	Crypteviant!
//	Providing tough encrypted P2P Chat
//	Copyright (C) 2010  Martin Pfeifer, Tobias Rausch
//
//	This program is free software: you can redistribute it and/or modify
//	it under the terms of the GNU General Public License as published by
//	the Free Software Foundation, either version 3 of the License, or
//	(at your option) any later version.
//
//	This program is distributed in the hope that it will be useful,
//	but WITHOUT ANY WARRANTY; without even the implied warranty of
//	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//	GNU General Public License for more details.
//
//	You should have received a copy of the GNU General Public License
//	along with this program.  If not, see <http://www.gnu.org/licenses/>.
// ============================================================================== */

#include "entropypool.hpp"


// Namespaces
using namespace RandomPool;

EntropyPool::EntropyPool(QObject *parent) :
    QObject(parent),
    m_cache(QString::null)
{
    // Save the optimal Block Size
    m_optimalBlockSize = m_data.optimalBlockSize();
}


void EntropyPool::addData(const QString data)
{
    QMutexLocker locker(&m_mutex);

    // Add new Data to the cache
    m_cache.append(data);

    locker.unlock();
    // Check the cache size and add to hash if necessary
    if (checkOptimalBlockSize())
    {
        locker.relock();
        m_data.addData(m_cache);
        m_cache.clear();
    }
}


QString EntropyPool::getData()
{
    forever /** @todo Should this loop really loop forever? */
    {
        // Add the cache if the amount of data is not enough
        if (m_data.size() < MINPOOLSIZE)
        {
            QMutexLocker locker(&this->m_mutex);
            m_data.addData(m_cache);
            m_cache.clear();
        }

        // Check if there is enough data available
        if (m_data.size() >= MINPOOLSIZE)
        {
            return m_data.getData();
        }

        m_data.wait();
    }
}


bool EntropyPool::dataAvailable()
{
    // Check if there is enough data available
    return (m_data.size() >= MINPOOLSIZE);
}


bool EntropyPool::checkOptimalBlockSize()
{
    QMutexLocker locker(&m_mutex);

    // Check if cache is a multiple of the optimal block size
    if ((m_cache.size() % m_optimalBlockSize) == 0)
    {
        return true;
    }

    // Check if cache gets too big
    if (((unsigned int) m_cache.size()) > (m_optimalBlockSize * MAXCACHETIME))
    {
        return true;
    }

    return false;
}
